import sa from './global'
import { isEmptyObject, isObject, extend, isDate, searchObjDate, searchObjString, base64Encode, isArray } from '../utils/index'
import { stripProperties } from './check'

sa.prepareData = function (p, callback) {
  var data = {
    distinct_id: sa.store.getDistinctId(),
    lib: {
      $lib: sa.lib.name,
      $lib_method: sa.lib.method,
      $lib_version: String(sa.lib.version)
    },
    properties: {}
  }

  data = extend(data, p)
  // 合并properties里的属性
  if (isObject(p.properties) && !isEmptyObject(p.properties)) {
    data.properties = extend(data.properties, p.properties)
  }

  // profile时不传公用属性
  if (!p.type || p.type.slice(0, 7) !== 'profile') {
    if (sa.para.batch_send) {
      data._track_id = Number(String(Math.random()).slice(2, 5) + String(Math.random()).slice(2, 4) + String(Date.now()).slice(-4))
    }
    // 传入的属性 > 当前页面的属性 > session的属性 > cookie的属性 > 预定义属性
    data.properties = extend({}, sa.properties, sa.currentProps, data.properties)

    // 判断是否是首日访问，果子说要做
    if (
      typeof sa.store._state === 'object' &&
      typeof sa.store._state.first_visit_day_time === 'number' &&
      sa.store._state.first_visit_day_time > new Date().getTime()
    ) {
      data.properties.$is_first_day = true
    } else {
      data.properties.$is_first_day = false
    }
  }
  if (data.properties.$time && isDate(data.properties.$time)) {
    data.time = data.properties.$time * 1
    delete data.properties.$time
  } else {
    data.time = new Date() * 1
  }

  stripProperties(data.properties)
  searchObjDate(data)
  searchObjString(data)

  if (!sa.para.server_url) {
    return false
  }
  sa.log(data)
  sa.send(data)
}

sa.send = function (t) {
  t._nocache = (String(Math.random()) + String(Math.random()) + String(Math.random())).slice(2, 15)

  if (sa.para.batch_send) {
    if (sa.batch_state.getLength() >= 300) {
      sa.log('数据量存储过大，有异常')
      return false
    }
    sa.batch_state.add(t)
    sa.batch_state.changed = true
    if (sa.batch_state.getLength() >= sa.para.batch_send.max_length) {
      batchSend()
    }
  } else {
    singleSend(t)
  }
}

sa.batch_state = {
  mem: [],
  changed: false,
  sended: true,
  is_first_batch_write: true,
  sync_storage: false, // 在初始化时将 storage 存的数据同步到当前暂存队列中的操作是否完成
  failTime: 0, // 发送数据失败次数
  getLength: function () {
    return this.mem.length
  },
  add: function (data) {
    this.mem.push(data)
  },
  clear: function (len) {
    this.mem.splice(0, len)
  }
}

export function singleSend(t) {
  t._flush_time = Date.now()
  var url = '',
    t = JSON.stringify(t)

  if (sa.para.server_url.indexOf('?') !== -1) {
    url = sa.para.server_url + '&data=' + encodeURIComponent(base64Encode(t))
  } else {
    url = sa.para.server_url + '?data=' + encodeURIComponent(base64Encode(t))
  }

  var timeout = sa.para.datasend_timeout
  sa.system_api.request({
    url: url,
    dataType: 'text',
    method: 'GET',
    timeout: timeout
  })
}

export function batchSend() {
  if (sa.batch_state.sended) {
    var data = sa.batch_state.mem
    var len = data.length
    if (len > 0) {
      sa.batch_state.sended = false
      batchRequest({
        data: data,
        len: len,
        success: batchRemove,
        fail: sendFail
      })
    }
  }
}

export function batchRequest(option) {
  if (isArray(option.data) && option.data.length > 0) {
    var now = Date.now(),
      timeout = sa.para.datasend_timeout
    option.data.forEach(function (v) {
      v._flush_time = now
    })
    option.data = JSON.stringify(option.data)
    let params = {
      url: sa.para.server_url,
      method: 'POST',
      dataType: 'text',
      data: 'data_list=' + encodeURIComponent(base64Encode(option.data)),
      timeout: timeout,
      success: function () {
        option.success(option.len)
      },
      fail: function () {
        option.fail()
      }
    }
    if (sa.lib && sa.lib.name === 'KuaishouMini') {
      params.header = { 'Content-Type': 'application/x-www-form-urlencoded' }
    }
    sa.system_api.request(params)
  } else {
    option.success(option.len)
  }
}

export function sendFail() {
  sa.batch_state.sended = true
  sa.batch_state.failTime++
}

export function batchRemove(len) {
  sa.batch_state.clear(len)
  sa.batch_state.sended = true
  sa.batch_state.changed = true
  batchWrite()
  sa.batch_state.failTime = 0
}

export function batchWrite() {
  if (sa.batch_state.changed) {
    // 如果是首次写入数据，等待1s后，优先发送，优化那些来了就跑的人
    if (sa.batch_state.is_first_batch_write) {
      sa.batch_state.is_first_batch_write = false
      setTimeout(function () {
        batchSend()
      }, 1000)
    }
    if (sa.batch_state.syncStorage) {
      sa.system_api.setStorageSync('sensors_prepare_data', sa.batch_state.mem)
      sa.batch_state.changed = false
    }
  }
}

export function batchInterval() {
  // 每隔1秒，写入数据
  function loopWrite() {
    setTimeout(function () {
      batchWrite()
      loopWrite()
    }, 1000)
  }
  // 默认每隔6秒，发送数据
  function loopSend() {
    setTimeout(function () {
      batchSend()
      loopSend()
    }, sa.para.batch_send.send_timeout * Math.pow(2, sa.batch_state.failTime))
  }
  loopWrite()
  loopSend()
}
